package com.gupao.rpc.discovery;

import com.gupao.rpc.discovery.loadbalance.LoadBalance;
import com.gupao.rpc.discovery.loadbalance.RandomLoadBalance;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.ArrayList;
import java.util.List;

public class ServiceDiscovery implements IServiceDiscovery {

    private CuratorFramework curatorFramework;

    private List<String> repos = new ArrayList<>();

    private String address;

    public ServiceDiscovery(String address) {
        this.address = address;
        curatorFramework = CuratorFrameworkFactory.builder()
                .connectString(address)
                .sessionTimeoutMs(4000)
                .retryPolicy(new ExponentialBackoffRetry(1000,10))
                .build();
        curatorFramework.start();
    }




    @Override
    public String discoveryService(String serviceName) {
        String servicePath = ZKConfig.ZK_REGISTRY_PATH+ "/" +serviceName;
        try {
            repos = curatorFramework.getChildren().forPath(servicePath);
            registerWatcher(servicePath);
            LoadBalance loadBalance = new RandomLoadBalance();
            String serviceAddress = loadBalance.selectHost(repos);
            return serviceAddress;
        } catch (Exception e) {
            System.out.println("获取子节点异常");
            e.printStackTrace();
        }
        return null;
    }

    public void registerWatcher(final String path){
        PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorFramework,path,true);
        PathChildrenCacheListener pathChildrenCacheListener = new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
                //监控子节点，子节点发生变化时，重新赋值
                repos = curatorFramework.getChildren().forPath(path);
            }
        };
        pathChildrenCache.getListenable().addListener(pathChildrenCacheListener);
        try {
            pathChildrenCache.start();
        } catch (Exception e) {
            System.out.println("注册PathChild---异常："+e);
            e.printStackTrace();
        }
    }

}
